/* * Copyright 2009-2014 Jose Luis Martin. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jdal.vaadin.beans; import java.util.List; import org.apache.commons.lang.StringUtils; import org.jdal.beans.BeanDefinitionUtils; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.parsing.CompositeComponentDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.NamespaceHandler; import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Parse <vaadin:table> element. * * @author Jose Luis Martin * @since 2.0 */ public class TableBeanDefinitionParser implements BeanDefinitionParser { private static final String ENTITY = "entity"; private static final String ID = "id"; private static final String PAGEABLE_TABLE_SUFFIX = "PageableTable"; private static final String TABLE_SUFFIX = "Table"; private static final String TABLE = "table"; private static final String SERVICE_SUFFIX = "Service"; private static final String EDITOR_SUFFIX = "Editor"; private static final String DATA_SOURCE = "service"; private static final String PAGINATOR_VIEW = "paginator"; private static final String PAGINATOR = "paginator"; private static final String COLUMNS = "columns"; private static final String ACTIONS = "actions"; private static final String USE_ACTIONS = "use-actions"; private static final String GUI_FACTORY = "guiFactory"; private static final String EDITOR = "editor"; private static final String EDITOR_NAME = "editorName"; private static final String FILTER = "filter"; private static final String FILTER_FORM = "filter-form"; private static final String TABLE_SERVICE = "tableService"; private static final String NAME = "name"; private static final String MESSAGE_SOURCE = "messageSource"; private static final String FIELD_FACTORY = "field-factory"; private static final String FIELD_FACTORY_PROPERTY = "tableFieldFactory"; private static final String SORT_PROPERTY = "sort-property"; private static final String ORDER = "order"; private static final String PAGE_SIZE = "page-size"; private static final String SELECTABLE = "selectable"; private static final String MULTISELECT = "multi-select"; private static final String ENTITY_CLASS="entityClass"; private static final String SCOPE = "scope"; private static final String PAGEABLE_TABLE_CLASS = "pageable-table-class"; private static final String TABLE_CLASS = "table-class"; private static final String DEFAULT_TABLE_CLASS = "org.jdal.vaadin.ui.table.ConfigurableTable"; private static final String DEFAULT_PAGEABLE_TABLE_CLASS = "org.jdal.vaadin.ui.table.PageableTable"; private static final String NATIVE_BUTTONS = "native-buttons"; private static final String PROPAGATE_SERVICE = "propagate-service"; private static final String CONTAINER_CLASS = "container-class"; private static final String DIALOG = "dialog"; /** * {@inheritDoc} */ @SuppressWarnings("rawtypes") public BeanDefinition parse(Element element, ParserContext parserContext) { // Defaults String entity = null; if (element.hasAttribute(ENTITY)) entity = element.getAttribute(ENTITY); String name = StringUtils.uncapitalize(StringUtils.substringAfterLast(entity, ".")); if (element.hasAttribute(ID)) name = element.getAttribute(ID); parserContext.pushContainingComponent( new CompositeComponentDefinition(name, parserContext.extractSource(element))); // Bean names String pageableTableBeanName = name + PAGEABLE_TABLE_SUFFIX; String tableBeanName = name + TABLE_SUFFIX; String dataSource = name + SERVICE_SUFFIX; String paginator = PAGINATOR_VIEW; String editor = name + EDITOR_SUFFIX; String actions = DefaultsBeanDefinitionParser.DEFAULT_TABLE_ACTIONS; String guiFactory = DefaultsBeanDefinitionParser.DEFAULT_GUI_FACTORY; String scope = BeanDefinition.SCOPE_PROTOTYPE; String pageableTableClass = DEFAULT_PAGEABLE_TABLE_CLASS; String tableClass = DEFAULT_TABLE_CLASS; if (element.hasAttribute(DATA_SOURCE)) dataSource = element.getAttribute(DATA_SOURCE); if (element.hasAttribute(PAGINATOR)) paginator = element.getAttribute(PAGINATOR); if (element.hasAttribute(ACTIONS)) actions = element.getAttribute(ACTIONS); if (element.hasAttribute(GUI_FACTORY)) guiFactory = element.getAttribute(GUI_FACTORY); if (element.hasAttribute(EDITOR)) editor = element.getAttribute(EDITOR); if (element.hasAttribute(SCOPE)) scope = element.getAttribute(SCOPE); if (element.hasAttribute(PAGEABLE_TABLE_CLASS)) pageableTableClass = element.getAttribute(PAGEABLE_TABLE_CLASS); if (element.hasAttribute(TABLE_CLASS)) tableClass = element.getAttribute(TABLE_CLASS); // create PageableTable BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(pageableTableClass); bdb.setScope(scope); bdb.addPropertyReference(DATA_SOURCE, dataSource); bdb.addPropertyReference(PAGINATOR_VIEW, paginator); bdb.addPropertyValue(NAME, pageableTableBeanName); bdb.addPropertyReference(TABLE, tableBeanName); bdb.addPropertyReference(GUI_FACTORY, guiFactory); bdb.addPropertyValue(EDITOR_NAME, editor); bdb.addPropertyValue(ENTITY_CLASS, entity); BeanDefinitionUtils.addPropertyReferenceIfNeeded(bdb, element, TABLE_SERVICE); BeanDefinitionUtils.addPropertyReferenceIfNeeded(bdb, element, FILTER); BeanDefinitionUtils.addPropertyReferenceIfNeeded(bdb, element, MESSAGE_SOURCE); BeanDefinitionUtils.addPropertyReferenceIfNeeded(bdb, element, FILTER_FORM); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, SORT_PROPERTY); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, ORDER); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, PAGE_SIZE); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, NATIVE_BUTTONS); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, PROPAGATE_SERVICE); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, CONTAINER_CLASS); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, DIALOG); if (!element.hasAttribute(USE_ACTIONS) || "true".equals(element.getAttribute(USE_ACTIONS))) bdb.addPropertyReference(ACTIONS, actions); parserContext.getDelegate().parseBeanDefinitionAttributes(element, pageableTableBeanName, null, bdb.getBeanDefinition()); BeanDefinitionHolder holder = new BeanDefinitionHolder(bdb.getBeanDefinition(), pageableTableBeanName); // Test Decorators like aop:scoped-proxy NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node n = childNodes.item(i); if (Node.ELEMENT_NODE != n.getNodeType() || COLUMNS.equals(n.getLocalName())) continue; NamespaceHandler handler = parserContext.getReaderContext() .getNamespaceHandlerResolver().resolve(n.getNamespaceURI()); if (handler != null) { holder = handler.decorate(n, holder, parserContext); } } parserContext.registerBeanComponent(new BeanComponentDefinition(holder)); // create ConfigurableTable bdb = BeanDefinitionBuilder.genericBeanDefinition(tableClass); bdb.setScope(BeanDefinition.SCOPE_PROTOTYPE); BeanDefinitionUtils.addPropertyValueIfNeeded(bdb, element, MULTISELECT); if (element.hasAttribute(FIELD_FACTORY)) bdb.addPropertyReference(FIELD_FACTORY_PROPERTY, element.getAttribute(FIELD_FACTORY)); if (element.hasAttribute(SELECTABLE)) { bdb.addPropertyValue(SELECTABLE, element.getAttribute(SELECTABLE)); } else { // set selectable by default bdb.addPropertyValue(SELECTABLE, true); } // parse columns NodeList nl = element.getElementsByTagNameNS(element.getNamespaceURI(), COLUMNS); if (nl.getLength() > 0) { List columns = parserContext.getDelegate().parseListElement( (Element) nl.item(0), bdb.getRawBeanDefinition()); bdb.addPropertyValue(COLUMNS, columns); } registerBeanDefinition(element, parserContext, tableBeanName, bdb); parserContext.popAndRegisterContainingComponent(); return null; } /** * Register BeanDefinition and apply default bean attributes. * @param element * @param parserContext * @param beanName * @param bdb */ private void registerBeanDefinition(Element element, ParserContext parserContext, String beanName, BeanDefinitionBuilder bdb) { AbstractBeanDefinition bd = bdb.getBeanDefinition(); parserContext.getDelegate().parseBeanDefinitionAttributes(element, beanName, null, bd); BeanComponentDefinition bcd = new BeanComponentDefinition(bdb.getBeanDefinition(), beanName); parserContext.registerBeanComponent(bcd); } }